﻿using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using Mvc3Demo.Core;

namespace Mvc3Demo.Extentions
{
    public static class HttpExtentions
    {
        private static readonly bool ConfigCheck;

        private static readonly ConcurrentDictionary<string, DeviceType> MobileDevicesList;

        static HttpExtentions()
        {
            var customSettins = ViewTypeSettings.Settings;

            ViewsInFolder = customSettins.ViewsInFolder;

            MobileDevicesList = new ConcurrentDictionary<string, DeviceType>();

            foreach (var viewType in customSettins.ViewTypes)
            {
                var newViewType = new DeviceType
                {
                    ViewType = viewType.Name,
                    DeviceIdentifiers = viewType.DeviceIdentifiers.ToLower().Split(',')
                };
                MobileDevicesList.AddOrUpdate(viewType.Name, newViewType, (k, p) => newViewType);
            }

            ConfigCheck = MobileDevicesList.Any();
        }

        public static bool ViewsInFolder { get; private set; }

        public static bool HasMobileSpecificViews
        {
            get { return ConfigCheck; }
        }

        /// <summary>
        /// Used to enable debugging using alternative devices
        /// </summary>
        /// <param name="request">The request.</param>
        /// <param name="deviceType">Type of the device.</param>
        /// <returns>
        ///   <c>true</c> if [is supported mobile device] [the specified request]; otherwise, <c>false</c>.
        /// </returns>
        public static bool IsSupportedMobileDevice(this HttpRequestBase request, out string deviceType)
        {
            var isMobile = request.Browser.IsMobileDevice;
            var userAgent = request.UserAgent.ToLowerInvariant();

            if (isMobile)
            {
                foreach (var deviceTypeKp in MobileDevicesList)
                {
                    foreach (var deviceIdentifier in deviceTypeKp.Value.DeviceIdentifiers)
                    {
                        if (userAgent.Contains(deviceIdentifier))
                        {
                            deviceType = deviceTypeKp.Key;
                            return true;
                        }
                    }
                }
            }

            deviceType = string.Empty;
            return isMobile;
        }

        /// <summary>
        /// Gets the name of the mobile views directory.
        /// </summary>
        /// <value>
        /// The name of the mobile views directory.
        /// </value>
        public static string GetMobileViewsDirectoryName(this HttpRequestBase request)
        {
            var directoryName = string.Empty;
            var userAgent = request.UserAgent.ToLowerInvariant();

            foreach (var deviceTypeKp in MobileDevicesList)
            {
                foreach (var deviceIdentifier in deviceTypeKp.Value.DeviceIdentifiers)
                {
                    if (userAgent.Contains(deviceIdentifier))
                        return deviceTypeKp.Key;
                }
            }


            return !string.IsNullOrEmpty(directoryName) ? String.Format("{0}/", directoryName) : string.Empty;
        }

        /// <summary>
        /// Gets the user ip address.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <returns></returns>
        public static string GetUserIpAddress(this HttpRequestBase request)
        {
            return request.UserHostAddress;
            //return request.ServerVariables["REMOTE_ADDR"];
        }

        /// <summary>
        /// Gets the name of the host.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <returns></returns>
        public static string GetHostName(this HttpRequestBase request)
        {
            var ip = Dns.GetHostEntry(request.UserHostName);
            return ip.HostName;
        }

        /// <summary>
        /// Determines whether the specified controller is authenticated.
        /// </summary>
        /// <param name="controller">The controller.</param>
        /// <returns>
        ///   <c>true</c> if the specified controller is authenticated; otherwise, <c>false</c>.
        /// </returns>
        public static bool IsAuthenticated(this Controller controller)
        {
            return controller.HttpContext.User.Identity.IsAuthenticated;
        }
    }

    internal class DeviceType
    {
        public string ViewType { get; set; }
        public string[] DeviceIdentifiers { get; set; }
    }
}